//ThreadPoolV1.hpp
//此版本的线程池是使用的是系统的pthread
#pragma once
#include <iostream>
#include <unistd.h>
#include <string>
#include <pthread.h>
#include <vector>
#include <queue>
#include "Task.hpp"
using namespace std;
#define SIZE 5
template<class T>
class ThreadPool
{
    public:
    ThreadPool(int size=SIZE)
    :_pool(size),
    _capacity(size)
    {
        pthread_mutex_init(&_mutex,nullptr);
        pthread_cond_init(&_cond,nullptr);
    }
    
    ~ThreadPool()
    {
       

        pthread_mutex_destroy(&_mutex);
        pthread_cond_destroy(&_cond);

    }

    void push(const T& task)
    {
        pthread_mutex_lock(&_mutex);
        _task.push(task);
        pthread_cond_signal(&_cond);//唤醒线程来执行task
        pthread_mutex_unlock(&_mutex);
       
    }


    static void* Routine(void* arg)
    {
        ThreadPool* tp=static_cast<ThreadPool*>(arg);
        while(1)
        {
            //所有的线程都在这里面运行，省去了创建和销毁的开销
            pthread_mutex_lock(&tp->_mutex);
            while(tp->_task.empty())//使用while而不是if可以更安全，即使意外唤醒了
            {
                pthread_cond_wait(&tp->_cond,&tp->_mutex);
            }
            T t=tp->_task.front();//获取任务
            tp->_task.pop();
            pthread_mutex_unlock(&tp->_mutex);
            t();//完成任务
            cout<<t.to_customer()<<endl;
        }
    }


    void Start()
    {
        for(int i=0;i<_capacity;i++)
        {
        pthread_create(&_pool[i],nullptr,Routine,this);
        }

    }



    private:
    vector<pthread_t> _pool;//线程池
    queue<T> _task;//任务
    int _capacity;//线程池的大小
    pthread_mutex_t _mutex;//保护task的资源
    pthread_cond_t _cond;//在没有task时进行一个等待
};